#include <iostream>
#include <sstream>
#include <iomanip>
#include <cmath>

std::string toFixed(double value, int decimals) {
    double multiplier = std::pow(10.0, decimals);
    double rounded = std::round(value * multiplier) / multiplier;
    
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(decimals) << rounded;
    return oss.str();
}

int main() {
    std::cout << "===============================================" << std::endl;
    std::cout << "        C++ toFixed(2) 综合测试" << std::endl;
    std::cout << "===============================================" << std::endl;

    // 例子1：基础测试
    std::cout << "\n=== 例子1：基础 toFixed 测试 ===" << std::endl;
    double value1 = 0.075;
    double value2 = 6.0/80;
    
    std::cout << std::fixed << std::setprecision(17);
    std::cout << "0.075 字面量: " << value1 << std::endl;
    std::cout << "6.0/80 计算:  " << value2 << std::endl;
    
    std::cout << "toFixed(2) 结果:" << std::endl;
    std::cout << "0.075 -> " << toFixed(value1, 2) << std::endl;
    std::cout << "6.0/80 -> " << toFixed(value2, 2) << std::endl;
    
    // 例子2：边界值测试
    std::cout << "\n=== 例子2：边界值测试 ===" << std::endl;
    
    double values[] = {
        0.075,                    // 字面量
        6.0/80,                   // 计算
        75.0/1000,                // 分数
        0.0750000000000001,       // 稍大的值
        0.074999999999999999,     // 接近但略小
        7.5/100.0,                // 另一种计算
        15.0/200.0                // 又一种计算
    };
    
    const char* descriptions[] = {
        "0.075 字面量",
        "6.0/80",
        "75.0/1000", 
        "0.0750000000000001",
        "0.074999999999999999",
        "7.5/100.0",
        "15.0/200.0"
    };
    
    for (int i = 0; i < 7; i++) {
        std::cout << descriptions[i] << ": " << values[i] 
                  << " -> toFixed(2): " << toFixed(values[i], 2) << std::endl;
    }
    
    // 例子3：复现之前的测试
    std::cout << "\n=== 例子3：复现之前的测试 ===" << std::endl;
    
    double testValue = 6.0/80;
    std::cout << "C++ 复刻 toFixed(2): " << toFixed(testValue, 2) << std::endl;
    std::cout << "实际值: " << testValue << std::endl;
    std::cout << "是否 < 0.075: " << (testValue < 0.075) << std::endl;
    std::cout << "是否 = 0.075: " << (testValue == 0.075) << std::endl;
    std::cout << "是否 > 0.075: " << (testValue > 0.075) << std::endl;
    
    // 详细舍入过程
    std::cout << "\n舍入过程分析:" << std::endl;
    std::cout << "value * 100 = " << (testValue * 100) << std::endl;
    std::cout << "round(value * 100) = " << std::round(testValue * 100) << std::endl;
    std::cout << "/ 100 = " << (std::round(testValue * 100) / 100) << std::endl;
    
    // 例子4：强制产生0.08的情况
    std::cout << "\n=== 例子4：强制产生 0.08 的测试 ===" << std::endl;
    
    double forceValues[] = {
        0.075000000000000001,     // 稍大于0.075
        0.076,                    // 明显大于0.075  
        0.0751,                   // 大于0.075
        std::nextafter(0.075, 1.0)  // 下一个可表示的浮点数
    };
    
    const char* forceDescriptions[] = {
        "0.075000000000000001",
        "0.076",
        "0.0751", 
        "nextafter(0.075, 1.0)"
    };
    
    for (int i = 0; i < 4; i++) {
        std::cout << forceDescriptions[i] << ": " << forceValues[i] 
                  << " -> toFixed(2): " << toFixed(forceValues[i], 2) << std::endl;
    }
    
    // 例子5：编译器差异测试
    std::cout << "\n=== 例子5：编译器和计算差异测试 ===" << std::endl;
    
    // 不同的计算方式
    volatile double a = 6;    // 使用volatile防止编译器优化
    volatile double b = 80;
    
    double method1 = 6.0/80;
    double method2 = a/b;
    double method3 = 6/80.0;
    double method4 = (double)6/(double)80;
    
    std::cout << "方法1 6.0/80:               " << method1 << " -> " << toFixed(method1, 2) << std::endl;
    std::cout << "方法2 volatile a/b:         " << method2 << " -> " << toFixed(method2, 2) << std::endl;
    std::cout << "方法3 6/80.0:               " << method3 << " -> " << toFixed(method3, 2) << std::endl;
    std::cout << "方法4 (double)6/(double)80: " << method4 << " -> " << toFixed(method4, 2) << std::endl;
    
    // 额外测试：十六进制表示
    std::cout << "\n=== 额外：十六进制表示对比 ===" << std::endl;
    std::cout << std::hexfloat;
    std::cout << "0.075 字面量: " << value1 << std::endl;
    std::cout << "6.0/80 计算:  " << value2 << std::endl;
    std::cout << "nextafter:    " << std::nextafter(0.075, 1.0) << std::endl;
    
    // 总结
    std::cout << "\n===============================================" << std::endl;
    std::cout << "                  测试总结" << std::endl;
    std::cout << "===============================================" << std::endl;
    std::cout << "如果所有测试都显示 '0.07'，说明在你的系统上" << std::endl;
    std::cout << "6.0/80 确实等于 0.075 字面量（都小于理论0.075）" << std::endl;
    std::cout << "如果有任何显示 '0.08'，那就是我们要找的情况！" << std::endl;
    
    return 0;
}

